package struts.action;

import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import util.SystemSettingUtil;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.EventDispatchAction;

/**
 * @author ben
 * 
 */
public abstract class LoggingDispatchAction extends EventDispatchAction {

	private static final Log log = LogFactory.getLog(LoggingDispatchAction.class);

	// 功能日志信息的格式
	protected static final MessageFormat format = new MessageFormat(SystemSettingUtil.getString("boardgame.resource.functionlog.format",
			"session ID:{0} 用户ID:{1} 功能ID:{2} 方法名:{3}"));

	@Override
	protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response, String name) throws Exception {

		// 生成操作的日志信息
		writeFunctionLog(mapping, form, request, response, name);

		return super.dispatchMethod(mapping, form, request, response, name);
	}

	/**
	 * <p>
	 * 生成功能日志信息
	 * </p>
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @param name
	 * @return
	 * @throws Exception
	 */
	protected void writeFunctionLog(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response,
			String name) {
		try {
			LogInfo logInfo = getLogInfo(mapping, form, request, response, name);

			// 记录功能日志信息
			log.info(format.format(new Object[] { logInfo.getSessionId(), logInfo.getUserId(), logInfo.getFunctionId(),
					logInfo.getMethodName(), ToStringBuilder.reflectionToString(form, ToStringStyle.SHORT_PREFIX_STYLE) }));
		} catch (Exception ignore) {
			log.error("log output error", ignore);
		}
	}

	protected abstract LogInfo getLogInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response,
			String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException;

	/**
	 * <p>
	 * 功能日志信息
	 * </p>
	 * 
	 * @author ben
	 * 
	 */
	public static class LogInfo {
		private String userId;
		private String functionId;
		private String methodName;
		private String sessionId;

		public LogInfo() {

		}

		public String getUserId() {
			return userId;
		}

		public void setUserId(String userId) {
			this.userId = userId;
		}

		public String getFunctionId() {
			return functionId;
		}

		public void setFunctionId(String functionId) {
			this.functionId = functionId;
		}

		public String getMethodName() {
			return methodName;
		}

		public void setMethodName(String methodName) {
			this.methodName = methodName;
		}

		public String getSessionId() {
			return sessionId;
		}

		public void setSessionId(String sessionId) {
			this.sessionId = sessionId;
		}
	}

}
